import logging

from openai import OpenAI
from datetime import datetime
import json

import funcall
from conf.config import AIConfigHandler
from funcall import baidu_search_fun_call
from funcall.baidu_search_fun_call import baidu_search
from funcall.searx_fun_call import searxng

# 设置 logging 级别为 DEBUG
logging.basicConfig(level=logging.DEBUG)

# url="http://localhost:11434/api/generate"
# url="https://api.deepseek.com"
# api_key = os.environ.get('DEEPSEEK_API_KEY')
# model="deepseek-r1:7b"

# 阿里云
# model="qwen-turbo-latest"
# url="https://dashscope.aliyuncs.com/compatible-mode/v1"
# api_key = os.environ.get('DASHSCOPE_API_KEY')
# print("api_key="+api_key)

appConf=AIConfigHandler().read_conf()

base_url=appConf['ai']['base_url']
api_key=appConf['ai']['api_key']
model=appConf['ai']['model']

client = OpenAI(
    # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key="sk-xxx",
    api_key=api_key,
    base_url=base_url,  # 填写DashScope SDK的base_url
)

# 定义工具列表，模型在选择使用哪个工具时会参考工具的name和description
tools = [
    # 工具1 获取当前时刻的时间
    {
        "type": "function",
        "function": {
            "name": "get_current_time",
            "description": "当你想知道现在的时间时非常有用。",
            # 因为获取当前时间无需输入参数，因此parameters为空字典
            "parameters": {}
        }
    },
    # 工具2 获取指定城市的天气
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "当你想查询指定城市的天气时非常有用。",
            "parameters": {
                "type": "object",
                "properties": {
                    # 查询天气时需要提供位置，因此参数设置为location
                    "location": {
                        "type": "string",
                        "description": "城市或县区，比如北京市、杭州市、余杭区等。"
                    }
                }
            },
            "required": [
                "location"
            ]
        }
    }
]
tools = []
fcs=funcall.fcs()
for fc in fcs:
    funNode={
        "type": "function",
        "function":vars(fc)
    }
    tools.append(funNode)
    # funcalltools.append(fc.to_json())


# 模拟天气查询工具。返回结果示例：“北京今天是雨天。”
def get_current_weather(location):
    return f"{location}今天是雨天。 "

# 查询当前时间的工具。返回结果示例：“当前时间：2024-04-15 17:15:18。“
def get_current_time():
    # 获取当前日期和时间
    current_datetime = datetime.now()
    # 格式化当前日期和时间
    formatted_time = current_datetime.strftime('%Y-%m-%d %H:%M:%S')
    # 返回格式化后的当前时间
    return f"当前时间：{formatted_time}。"

# 封装模型响应函数
def get_response(messages):
    # print(f"{funcalltools}")
    completion = client.chat.completions.create(
        model=model,
        messages=messages,
        tools=tools
        )
    return completion.model_dump()

def call_openai(messages):
    get_response(messages)


cw = baidu_search_fun_call()


def call_with_messages(msg):
    messages =[]
    web_result=searxng(msg)
    # web_result=baidu_search(msg)
    # args = {"search_text": msg,'remark': 'test'}
    # result = cw.call(args)
    # results_list=json.loads(result)
    # results_list=results_list['content']
    # results_list=json.loads(results_list)
    # print(f"\n\n\nresults_list={results_list}")
    # web_result = ""
    # if results_list:
    #     for results_item in results_list:
    #         title = results_item.get("title", "")
    #         content = results_item.get("abstract", "")
    #         url = results_item.get("url", "")
    #         if title and content:
    #             web_result = (
    #                     web_result + "标题：" + title + "\n" + "内容：" + content + "\n\n"+"链接:"+url+"\n\n"
    #             )
    print(web_result)
    print('\n')
    messages = [
        {
            "content": "基于以下搜索结果回答问题："+web_result,  # 网页搜索结果
            "role": "system"
        },
            {
                "content": msg,  # 提问示例："现在几点了？" "一个小时后几点" "北京天气如何？"
                "role": "user"
            }
    ]
    print("-"*60)
    # 模型的第一轮调用
    i = 1
    first_response = get_response(messages)
    res_choice = first_response['choices'][0]
    assistant_output = res_choice['message']
    print(f"\n第{i}轮大模型输出信息：{first_response}\n")
    if  assistant_output['content'] is None:
        assistant_output['content'] = ""
    messages.append(assistant_output)
    # 如果不需要调用工具，则直接返回最终答案
    if assistant_output['tool_calls'] == None:  # 如果模型判断无需调用工具，则将assistant的回复直接打印出来，无需进行模型的第二轮调用
        print(f"无需调用工具，我可以直接回复：{assistant_output['content']}")
        return
    # 如果需要调用工具，则进行模型的多轮调用，直到模型判断无需调用工具
    while assistant_output['tool_calls'] != None:
        for res_call in assistant_output['tool_calls']:
        #     res_call = assistant_output['tool_calls'][0]
            res_fun = res_call['function']
            f_name= res_fun['name']
            for fc in fcs:
                if f_name==fc.name:
                    res_role = assistant_output['role'] if assistant_output['role'] != None else 'funcalltools'
                    # tool_info = {"name": f_name, "role": res_role}
                    tool_info = {"name": f_name, "role": 'funcalltools'}
                    tool_info['id'] = res_call['id']
                    tool_info['content']=fc.call(json.loads(res_fun['arguments']))
                    break

            # # 如果判断需要调用查询天气工具，则运行查询天气工具
            # if assistant_output['tool_calls'][0]['function']['name'] == 'get_current_weather':
            #     tool_info = {"name": "get_current_weather", "role":"funcalltools"}
            #     # 提取位置参数信息
            #     location = json.loads(assistant_output['tool_calls'][0]['function']['arguments'])['location']
            #     # tool_info['content'] = get_current_weather(location)
            #     tool_info['content'] = funcall.GetCurrentWeatherFunCall(location);
            # # 如果判断需要调用查询时间工具，则运行查询时间工具
            # elif assistant_output['tool_calls'][0]['function']['name'] == 'get_current_time':
            #     tool_info = {"name": "get_current_time", "role":"funcalltools"}
            #     tool_info['content'] = get_current_time()
            #

            print(f"工具输出信息：{tool_info['content']}\n")
            print("-"*60)
            messages.append(tool_info)
            #需要改下,不要调一次工具就
        assistant_output = get_response(messages)['choices'][0]['message']
        if  assistant_output['content'] is None:
            assistant_output['content'] = ""
        messages.append(assistant_output)
        i += 1
        print(f"第{i}轮大模型输出信息：{assistant_output}\n")
    print(f"最终答案：{assistant_output['content']}")

if __name__ == '__main__':
    #本机 ollama 的 qwen2.5:7b 模型刚启动时运行正常,昨晚出现几次不行,估计算力不够
    msg="杭州天气如何,现在几点了"
    msg="杭州天气如何"
    # msg="俄乌战争"

    call_with_messages(msg)